#ifndef VL_PCL_PCL_HPP
#define VL_PCL_PCL_HPP

#include <cstddef>
#include <stdexcept>

namespace pcl
{

struct error : std::runtime_error
{
	error(std::string const& text)
	: std::runtime_error(text)
	{
	}
};

struct coro_impl;

struct coro
{
	struct main_tag
	{};
	
	enum
	{
		done = (1<<0)
	};
	
	coro(std::size_t stack_size = 0);
	
	coro(main_tag)
	: impl(0), flags(0)
	{
	}
	
	virtual ~coro();
		
	void call();
	void exit_to();
	
	void clean_up();
	
	bool is_done()
	{
		return (flags & done) != 0;
	}
	
	virtual void go() // Entry point
	{
	}
	
	coro_impl* impl; // Private implementation
	coro* caller;
	coro* restarget;
	int   flags;
};

#ifdef ENABLE_AUTO_SCHEDULER
struct scheduler
{
	virtual coro* next() = 0;
	
	virtual ~scheduler();
	
	coro* org_coro; // The coro the scheduler was launched from
};
#endif

void resume();
void exit();
coro* current();

#ifdef ENABLE_AUTO_SCHEDULER
void yield();
void set_scheduler(scheduler*);
#endif

/*
coroutine_t co_create(void (*func)(void *), void *data, void *stack, int size);
void co_delete(coroutine_t coro);
void co_call(coroutine_t coro);
void co_resume(void);
void co_exit_to(coroutine_t coro);
void co_exit(void);
coroutine_t co_current(void);*/

}

#endif // VL_PCL_PCL_HPP
